import akka.actor.Actor
import java.io.PrintWriter
import java.lang.System

abstract class ActorLogger extends Actor{
    val writer = new PrintWriter(self.path.name + ".log")
    
	def receive = {
      case whatever => 
        {
          val time = System.nanoTime.toString
          val from = sender.path.toString()
          val to = getNode.toJson
          
          receiveMessage(whatever)
          
          val what = msgToJson(whatever)
          val json = "{\"time\": \"" + time + "\", \"from\": \"" + from + "\", \"to\": " + to + ", \"what\": " + what + "}"

          writer.println(json)
        }
	}
    
    def msgToJson(msg : Any) : String = msg match {
      case Start(nOfNodes, nOfMessages) => {startToJson}
      case StartSending => {startSendingToJson}
	  case StartDone => {startDoneToJson}
	  case Route(id, key, requestor, routeCount) => {RouteToJson(id, key, requestor, routeCount)}
	  case RouteResponse(id, node, routeCount) => {RouteResponseToJson(id, node, routeCount)}
	  case Join(id, newNode) => {JoinToJson(id, newNode)}
	  case JoinResponse(id, respondingNode, tableRow, row, leaf, lastResponce) => {JoinResponseToJson(id, respondingNode, tableRow, row, leaf, lastResponce)}
	  case JoinDone(id, respondingNode, table, tableTime, leaf) => {JoinDoneToJson(id, respondingNode, table, tableTime, leaf)}
	  case Done(avg) => {DoneToJson(avg)}
	  case _ => "{ \"type\": \"?\" }"
    }
    
    def startToJson = "{ \"type\": \"Start\" }"
    def startSendingToJson = "{ \"type\": \"StartSending\" , \"state\" : "+stateToJson+" }"	
    def startDoneToJson = "{ \"type\": \"StartDone\" }"
    def RouteToJson(id : String, key : String, requestor : String, routeCount : Integer) : String = {
      "{ \"type\": \"Route\", \"content\": {\"id\":\""+id+"\", \"key\":\""+key+"\", \"requestor\":\""+requestor+"\", \"routeCount\":\""+routeCount+"\"} }"
    }
    def RouteResponseToJson(id : String, node : NodeEntry, routeCount : Integer): String = {
      "{ \"type\": \"RouteResponse\", \"content\": {\"id\":\""+id+"\", \"node\":"+node.toJson+", \"routeCount\":\""+routeCount+"\"} }"
    }
    def JoinToJson(id : String, newNode : NodeEntry): String = {
      "{ \"type\": \"Join\", \"content\": {\"id\":\""+id+"\", \"newNode\":"+newNode.toJson+"} }"
    }
    def JoinResponseToJson(id : String, respondingNode : NodeEntry, tableRow : Array[NodeEntry], row : Integer, leaf : Leaf, lastResponce : Boolean): String = {
      "{ \"type\": \"JoinResponse\", \"content\": {\"id\":\""+id+"\", \"respondingNode\":"+respondingNode.toJson+" }}"
    }
    def JoinDoneToJson(id : String, respondingNode : NodeEntry, table : Array[Array[NodeEntry]], tableTime : Long, leaf : Leaf): String = {
      "{ \"type\": \"JoinDone\", \"content\": {\"id\":\""+id+"\", \"respondingNode\":"+respondingNode.toJson+" }}"
    }
    def DoneToJson(avg : Double): String = "{ \"type\": \"Done\" }"

    def arrayToJson(tableRow : Array[NodeEntry]) : String = {
		var json = "["
	 
	    for (j <- 0 to tableRow.length-1){
	      if (tableRow(j) != null){
	      	json += tableRow(j).toJson + ","
	      }
	      else{
	      	json += "{},"
	      }
	    }
	    if (json.last == ','){ 
	      json = json.substring(0, json.length()-1)
	    }
	    
	    json += "]"  
	    json  
    }  
    
    def arrayToJson(table : Array[Array[NodeEntry]]) : String = {
      var json = "["
	  for (i <- 0 to table.length-1){
	    json += arrayToJson(table(i))
	    if (i < table.length-1) { json += ","}  
	  }
	  
	  json += "]"  
	  json  
    } 
    
    def stateToJson() : String = {
      var json = "{"
        
      json += "\"leaf\":"
	  json += getLeaf.toJson
	  json += ","
	    
	  json += "\"table\":"
      json += getTable.toJson
      
      json += "}"
      json  
    }
    
    override def postStop() {
      writer.close()
    }
    
    def receiveMessage(msg : Any)
    
    def getNode() : NodeEntry
    
    def getLeaf() : Leaf
    
    def getTable() : RoutingTable
    
    
}